package DAO;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class AbsHbnDao<T extends Object> implements DAO<T> {
	
	private static final String FIND_MAX = "Select max( ? ) from ?";
	//
	
	@Autowired
	private SessionFactory sessionFactory;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	private Class<T> domainClass;

	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings({ "unchecked", "unused" })
	private Class<T> getDomainClass() {
		if (domainClass == null) {
			ParameterizedType thisType = (ParameterizedType) getClass()
					.getGenericSuperclass();
			this.domainClass = (Class<T>) thisType.getActualTypeArguments()[0];
		}
		return this.domainClass;
	}

	@SuppressWarnings("unused")
	private String getDomainClassName() {
		//System.out.println("class name "+getDomainClass().getName());
		return getDomainClass().getName();
	}

	public int create(T t) {
/*		Method method = ReflectionUtils.findMethod(getDomainClass(),
				"setDateCreated", new Class[] { Date.class });
		if (method != null) {
			try {
				method.invoke(t, new Date());
			} catch (Exception e) {
				 Ignore 
			}
			getSession().save(t);
		}*/
		//Transaction tx = getSession().beginTransaction();
		Serializable s = getSession().save(t);
		if (s instanceof Integer)
			return (Integer) s;
		return -1;
		//tx.commit();
	}

	@SuppressWarnings("unchecked")
	public T get(Serializable id) {
		return (T) getSession().get(getDomainClass(), id);
	}

	@SuppressWarnings("unchecked")
	public T load(Serializable id) {
		return (T) getSession().load(getDomainClass(), id);
	}

	@SuppressWarnings("unchecked")
	public List<T> getAll() {
		return getSession().createQuery("from " + getDomainClassName()).list();
	}

	public void update(T t) {
		getSession().update(t);
	}

	public void delete(T t) {
		getSession().delete(t);
	}

	public void deleteById(Serializable id) {
		delete(load(id));
	}

	public void deleteAll() {
		getSession().createQuery("delete " + getDomainClassName())
				.executeUpdate();
	}

	public long count() {
		return (Long) getSession().createQuery(
				"select count(*) from " + getDomainClassName()).uniqueResult();
	}

	public int getMax(String propertyName) {
/*		System.out.println("class name " +getDomainClassName());
		return (Integer) getSession().createQuery(FIND_MAX)
				.setString(0, "priority")
				.setString(1, "Category")
				.uniqueResult();*/
		System.out.println("no implement");
		return -1;
	}
	
	public boolean exists(Serializable id) {
		return (get(id) != null);
	}
}
